package com.hz.cheetah.common.sys;

/**
 * Created by yangchuan on 16/6/28.
 */

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Iterator;
import java.util.LinkedList;

public class MonitorRuntime extends JvmRuntime {
    private static MonitorRuntime runtime = null;
    private LinkedList<ShutdownHook> shutdownHooks = new LinkedList();

    private MonitorRuntime() {
        Runtime.getRuntime().addShutdownHook(new MonitorRuntime.MainShutdownThread());
    }

    public static MonitorRuntime getMonitorRuntime() {
        if(runtime == null) {
            Class var0 = MonitorRuntime.class;
            synchronized(MonitorRuntime.class) {
                if(runtime == null) {
                    runtime = new MonitorRuntime();
                }
            }
        }

        return runtime;
    }

    public synchronized void addShutdownHook(ShutdownHook hook) {
        this.shutdownHooks.add(hook);
    }

    private class MainShutdownThread extends Thread {
        public MainShutdownThread() {
            this.setName("MainShutdownThread");
        }

        public void run() {
            LinkedList thlist = new LinkedList();
            ThreadGroup threads = new ThreadGroup(Thread.currentThread().getThreadGroup(), "Tigase Shutdown");
            Iterator shutdownStart = MonitorRuntime.this.shutdownHooks.iterator();

            while(shutdownStart.hasNext()) {
                ShutdownHook shutdownHook = (ShutdownHook)shutdownStart.next();
                MonitorRuntime.ShutdownHandlerThread sb = MonitorRuntime.this.new ShutdownHandlerThread(threads, shutdownHook);
                sb.start();
                thlist.add(sb);
            }

            long var19 = System.currentTimeMillis();

            while(threads.activeCount() > 0 && System.currentTimeMillis() - var19 < 10000L) {
                try {
                    sleep(100L);
                } catch (Exception var18) {
                    ;
                }
            }

            StringBuilder sb = new StringBuilder();
            Iterator thBean = thlist.iterator();

            while(thBean.hasNext()) {
                MonitorRuntime.ShutdownHandlerThread tids = (MonitorRuntime.ShutdownHandlerThread)thBean.next();
                if(tids.getResultMessage() != null) {
                    sb.append(tids.getResultMessage());
                }
            }

            ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
            sb.append("\nTotal number of threads: " + threadMXBean.getThreadCount()).append('\n');
            long[] var22 = threadMXBean.findDeadlockedThreads();
            if(var22 != null && var22.length > 0) {
                sb.append("Locked threads:\n");
                ThreadInfo[] lockedThreads = threadMXBean.getThreadInfo(var22);
                int len = lockedThreads.length;

                for(int i = 0; i < len; ++i) {
                    ThreadInfo threadInfo = lockedThreads[i];
                    sb.append("Locked thread " + threadInfo.getThreadName() + " on " + threadInfo.getLockInfo().toString()).append('\n');
                    StackTraceElement[] ste = threadInfo.getStackTrace();
                    int length = ste.length;

                    for(int j = 0; j < length; ++j) {
                        StackTraceElement stackTraceElement = ste[j];
                        sb.append(stackTraceElement.toString()).append('\n');
                    }
                }
            } else {
                sb.append("No locked threads.\n");
            }

            if(sb.length() > 0) {
                ;
            }

        }
    }

    private class ShutdownHandlerThread extends Thread {
        private ShutdownHook hook = null;
        private String result = null;

        public ShutdownHandlerThread(ThreadGroup group, ShutdownHook hook) {
            super(group, hook.getName());
            this.hook = hook;
            this.setDaemon(true);
        }

        public void run() {
            this.result = this.hook.shutdown();
        }

        public String getResultMessage() {
            return this.result;
        }
    }
}

